package com.kingdee.spider.model;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.ICompilationUnit;

public class JavaCodeBuilder {

	private List<TypeDeclarationCode> types;

	private RestoreStack<TypeDeclarationCode> typeStack;
	private RestoreStack<MethodDeclarationCode> methodStack;

	private TypeDeclarationCode currentTypeDeclaration;
	private MethodDeclarationCode currentMethodDeclaration;

	private ICompilationUnit compilationUnit;

	public JavaCodeBuilder() {
		super();
		types = new ArrayList<TypeDeclarationCode>();
		typeStack = new RestoreStack<TypeDeclarationCode>();
		methodStack = new RestoreStack<MethodDeclarationCode>();
	}

	public void buildTypeDeclaration(final ICompilationUnit compilationUnit, final int offset, final int length, final String typeName) {
		this.compilationUnit = compilationUnit;
		final TypeDeclarationCode oldTypeDeclaration = this.currentTypeDeclaration;
		typeStack.save(this.currentTypeDeclaration);
		this.currentTypeDeclaration = new TypeDeclarationCode(typeName);
		this.currentTypeDeclaration.setCodeLocation(compilationUnit, offset, length);
		if (oldTypeDeclaration != null) {
			oldTypeDeclaration.addChild(this.currentTypeDeclaration);
		}
		types.add(this.currentTypeDeclaration);
	}

	public void endBuildTypeDeclaration() {
		currentTypeDeclaration = typeStack.loadCurrentType();
	}

	public void buildMethodDeclaration(final int offset, final int length, final String methodName) {
		methodStack.save(this.currentMethodDeclaration);
		this.currentMethodDeclaration = new MethodDeclarationCode(methodName);
		this.currentMethodDeclaration.setCodeLocation(compilationUnit, offset, length);
		currentTypeDeclaration.addChild(currentMethodDeclaration);
	}

	public void endBuildMethodDeclaration() {
		this.currentMethodDeclaration = methodStack.loadCurrentType();
	}

	public void buildMethodInvocation(final int offset, final int length, final String methodName) {
		MethodInvocationCode methodInvocation = new MethodInvocationCode(methodName);
		methodInvocation.setCodeLocation(compilationUnit, offset, length);
		this.currentMethodDeclaration.addChild(methodInvocation);
	}

	public List<TypeDeclarationCode> getResult() {
		return types;
	}
}